        #include "inkview.h"
        #include "muParser.h"

        #define buflen 1024
        char expr[buflen];

        double x11 = -10,
        	   x22 = 10,
	           y11 = -7.5,
	           y22 = 7.5;

        double stepX = (x22-x11)/800;
        double stepY = (y22-y11)/600;

        std::vector<std::string> funcs;
        bool first = true,
        update = true;

		double px = (x22 - x11)/4,
		py = (y22 - y11)/4;

        #include "plot.cpp"

        unsigned int histPos = 0;

        static imenu history[] =
        {
                {ITEM_SEPARATOR, 120, NULL, NULL},
                {0, 121, NULL, NULL},
                {0, 122, NULL, NULL},
                {0, 123, NULL, NULL},
                {0, 124, NULL, NULL},
                {0, 125, NULL, NULL},
                {0, 126, NULL, NULL}
        };

        static imenu zoom[] =
        {
                {ITEM_BULLET, 102, (char *)"По оси X", NULL},
                {ITEM_BULLET, 103, (char *)"По оси Y", NULL},
                {0, 0, NULL, NULL}
        };

        static imenu menu[] =
        {
				{ITEM_BULLET, 101, (char *)"Построить новый график", NULL },
                {ITEM_INACTIVE, 0, (char *)"Редактировать функцию из истории", history},
                {ITEM_HIDDEN, 0, (char *)"Изменять масштаб", zoom},
                {ITEM_HIDDEN, 104, (char *)"Перейти в (0;0)", NULL},
                {ITEM_HIDDEN, 105, (char *)"Сбросить масштаб", NULL},
                {ITEM_ACTIVE, 106, (char *)"Обновить", NULL},
                {ITEM_SEPARATOR, 0, NULL, NULL},
                {ITEM_ACTIVE, 107, (char *)"Выход", NULL},
                {0, 0, NULL, NULL}
        };

        char help[1024] = "";

        void keybfunc(char *buf)
        {
                if (buf)
                {
                        if (buf[0]=='?')
                             Message(ICON_INFORMATION,
                             (char *)"Поддерживаемые функции:",      help, 60000);
                        else
                        {
                                menu[1].type = ITEM_SUBMENU;
                                menu[2].type = ITEM_SUBMENU;
                                menu[3].type = ITEM_ACTIVE;
                                menu[4].type = ITEM_ACTIVE;
                                history[histPos].type = ITEM_ACTIVE;
                                history[histPos].text = new char[1024];
                                strcpy(history[histPos].text, buf);
                                histPos++;
                                if (histPos==7)
                                        histPos = 0;
                                plot();
                         }
                }
        }

        void drawAll()
        {
                ClearScreen();
                drawAxis();
                update = false;
                std::vector<std::string>::iterator i;
                for (i = funcs.begin(); i<funcs.end(); i++)
                {
                        strcpy(expr, (*i).c_str());
                        draw();
                }
                FullUpdate();
                update = true;
        }

        void menu_listener(int index)
        {
                switch (index)
                {
                    case 101:
                        OpenKeyboard
                                ("Введите выражение. Знак вопроса для справки.",
                                        expr, buflen, 0, keybfunc);
                        break;
                    case 102:
                        zoom[0].type = zoom[0].type==ITEM_BULLET ?
                                               ITEM_ACTIVE : ITEM_BULLET;
                        break;
                    case 103:
                        zoom[1].type = zoom[1].type==ITEM_BULLET ?
                                               ITEM_ACTIVE : ITEM_BULLET;
                        break;
                    case 104:
                        x11 = -2*px;
                        x22 =  2*px;
                        y11 = -2*py;
                        y22 =  2*py;
                        drawAll();
                        break;
                case 105:
                {
                        double x00 = x11+px*2,
                               y00 = y11+py*2;
                        x11 = x00-10;
                                x22 = x00+10;
                                y11 = y00-7.5;
                                y22 = y00+7.5;
                                px = (x22 - x11)/4;
                                py = (y22 - y11)/4;
                                stepX = (x22-x11)/800;
                                stepY = (y22-y11)/600;
                                drawAll();
                        break;
                }
                case 106:
                        FullUpdate();
                        break;
                    case 107:
                        CloseApp();
                        break;
                }
                if ((index>=120)&&(index<=126))
                {
                        strcpy(expr, history[index-120].text);
                        menu_listener(101);
                }
        }

        int shiftx = 0, shifty = 0;

        int listener(int type, int par1, int par2)
        {
                if (type==EVT_INIT)
                {
                        SetFont(OpenFont(DEFAULTFONT, 30, 1), 0x000000);
                        DrawTextRect(150, 0, 500, 600,
                        "Для открытия главного меню удерживайте палец на экране.",
                                ALIGN_CENTER | VALIGN_MIDDLE);
                        sprintf(expr,(char *)"sqrt(36-x^2)");
                }
                if (type==EVT_SHOW)
                        FullUpdate ();
                if (type==EVT_KEYPRESS)
                {
                        if (par1==KEY_MENU)
                                listener(EVT_POINTERLONG, 500, 400);
                        if ((par1==24)||(par1==KEY_UP))
                        {
                                if (!first)
                                {
                                        if (zoom[0].type==ITEM_BULLET)
                                        {
                                                x11 += px;
                                                x22 -= px;
                                                px /= 2;
                                                stepX = (x22-x11)/800;
                                        }
                                        if (zoom[1].type==ITEM_BULLET)
                                        {
                                                y11 += py;
                                                y22 -= py;
                                                py /= 2;
                                                stepY = (y22-y11)/600;
                                        }
                                        drawAll();
                                }
                        }
                        if ((par1==25)||(par1==KEY_DOWN))
                        {
                                if (!first)
                                {
                                        if (zoom[0].type==ITEM_BULLET)
                                        {
                                                px *= 2;
                                                x11 -= px;
                                                x22 += px;
                                                stepX = (x22-x11)/800;
                                        }
                                        if (zoom[1].type==ITEM_BULLET)
                                        {
                                                py *= 2;
                                                y11 -= py;
                                                y22 += py;
                                                stepY = (y22-y11)/600;
                                        }
                                drawAll();
                            }
                        }
                }
                if (type==EVT_POINTERLONG)
                        OpenMenu(menu, 0, par1, par2, menu_listener)
                if (type==EVT_POINTERDOWN)
                {
                        shiftx = par1;
                        shifty = par2;
                }
                if (type==EVT_POINTERUP)
                {
                        if (!first)
                        {
                                shiftx -= par1;
                                shifty = par2 - shifty;
                                x11 += shiftx * stepX;
                                x22 += shiftx * stepX;
                                y11 += shifty * stepY;
                                y22 += shifty * stepY;
                        drawAll();
                        }
                }

                return 0;
        }

        int main(int argc, char **argv)
        {
                strcat(help, "sin, cos, tan, asin, acos, atan, \n");
                strcat(help, "sinh, cosh, tanh, asinh, acosh, atanh, \n");
                strcat(help, "log2, log10 (log), ln, \n");
                strcat(help, "exp, sqrt, sign, rint, abs, \n");
                strcat(help, "min, max, sum, avg. \n\n");
                strcat(help, "Константы: _e, _pi");

                OpenScreen();
                SetOrientation(1);
                InkViewMain(listener);
                return 0;
        }
